//
// Created by lz on 2021/2/17.
//

#include "Buffer.h"
#include "net/SocketsOps.h"

#include <errno.h>

// The <sys/uio.h> header shall define the iovec structure
// The <sys/uio.h> header uses the iovec structure for scatter/gather I/O
#include <sys/uio.h>

using namespace lzweb;
using namespace lzweb::net;

const char Buffer::kCRLF[] = "\r\n";

const size_t Buffer::kCheapPrepend;
const size_t Buffer::kInitialSize;


// 将某个文件描述符的数据读取进来
ssize_t Buffer::readFd(int fd, int* savedErrno)
{
	char extrabuf[65536];
	struct iovec vec[2];
	const size_t writable = writableBytes();
	vec[0].iov_base = begin()+writerIndex_;
	vec[0].iov_len = writable;
	vec[1].iov_base = extrabuf;
	vec[1].iov_len = sizeof extrabuf;

	// when there is enough space in this buffer, don't read into extrabuf.
	// when extrabuf is used, we read 128k-1 bytes at most.
	const int iovcnt = (writable < sizeof extrabuf)? 2:1;

	const ssize_t n = sockets::readv(fd,vec,iovcnt);

	if(n < 0)
	{
		*savedErrno = errno;
	}
	else if (implicit_cast<size_t>(n) <=writable)
	{
		writerIndex_+=n;
	}else
	{
		writerIndex_ = buffer_.size();
		append(extrabuf, n - writable);
	}

	return n;
}
